package com.smartaccounting.controller;

import com.smartaccounting.dao.ExpenseDAO;
import com.smartaccounting.model.Expense;
import com.smartaccounting.model.User;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.time.LocalDate;

@WebServlet("/expense")
public class ExpenseServlet extends HttpServlet {
    private ExpenseDAO expenseDAO;

    @Override
    public void init() throws ServletException {
        expenseDAO = new ExpenseDAO();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String action = request.getParameter("action");

        try {
            switch (action) {
                case "list":
                    listExpenses(request, response);
                    break;
                case "new":
                    showNewForm(request, response);
                    break;
                case "edit":
                    showEditForm(request, response);
                    break;
                case "delete":
                    deleteExpense(request, response);
                    break;
                default:
                    listExpenses(request, response);
                    break;
            }
        } catch (SQLException e) {
            throw new ServletException(e);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String action = request.getParameter("action");

        try {
            switch (action) {
                case "insert":
                    insertExpense(request, response);
                    break;
                case "update":
                    updateExpense(request, response);
                    break;
            }
        } catch (SQLException e) {
            throw new ServletException(e);
        }
    }

    private void listExpenses(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, ServletException, IOException {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");

        String monthYear = request.getParameter("monthYear");
        if (monthYear == null) {
            monthYear = LocalDate.now().getYear() + "-" + String.format("%02d", LocalDate.now().getMonthValue());
        }

        request.setAttribute("expenses", expenseDAO.getExpensesByUserIdAndMonth(user.getUserId(), monthYear));
        request.setAttribute("monthYear", monthYear);
        request.getRequestDispatcher("user/expense.jsp").forward(request, response);
    }

    private void showNewForm(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.getRequestDispatcher("user/expense-form.jsp").forward(request, response);
    }

    private void showEditForm(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, ServletException, IOException {
        int expenseId = Integer.parseInt(request.getParameter("expenseId"));
        Expense existingExpense = expenseDAO.getExpenseById(expenseId);
        request.setAttribute("expense", existingExpense);
        request.getRequestDispatcher("user/expense-form.jsp").forward(request, response);
    }

    private void insertExpense(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");

        BigDecimal amount = new BigDecimal(request.getParameter("amount"));
        String category = request.getParameter("category");
        String paymentMethod = request.getParameter("paymentMethod");
        LocalDate expenseDate = LocalDate.parse(request.getParameter("expenseDate"));
        String description = request.getParameter("description");

        Expense newExpense = new Expense(user.getUserId(), amount, category, paymentMethod, expenseDate, description);
        expenseDAO.addExpense(newExpense);
        response.sendRedirect("expense?action=list");
    }

    private void updateExpense(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException {
        int expenseId = Integer.parseInt(request.getParameter("expenseId"));
        BigDecimal amount = new BigDecimal(request.getParameter("amount"));
        String category = request.getParameter("category");
        String paymentMethod = request.getParameter("paymentMethod");
        LocalDate expenseDate = LocalDate.parse(request.getParameter("expenseDate"));
        String description = request.getParameter("description");

        Expense expense = new Expense(expenseId, 0, amount, category, paymentMethod, expenseDate, description, null);
        expenseDAO.updateExpense(expense);
        response.sendRedirect("expense?action=list");
    }

    private void deleteExpense(HttpServletRequest request, HttpServletResponse response)
            throws SQLException, IOException {
        int expenseId = Integer.parseInt(request.getParameter("expenseId"));
        expenseDAO.deleteExpense(expenseId);
        response.sendRedirect("expense?action=list");
    }
}